package org.lib.mysqlhello;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

import javax.annotation.Resource;

import org.lib.mysqlhello.user.entity.User;
import org.lib.mysqlhello.user.repository.UserCrudRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.core.RedisTemplate;

import lombok.extern.slf4j.Slf4j;

@SpringBootApplication
//@EnableAspectJAutoProxy
// 开启缓存
@EnableCaching
@Slf4j
public class MysqlHelloApplication {

	private static Consumer<Object> cs = System.out::println;
	
	public static void main(String[] args) {
		ConfigurableApplicationContext ctx = SpringApplication.run(MysqlHelloApplication.class, args);

		// 调试用
//		studyContext(ctx);
	}
	
	/**
	 * 调试用：检查ApplicationContext
	 * @author ben
	 * @date 2021-08-26 10:20:56 CST
	 * @param ctx
	 */
	public static void studyContext(ConfigurableApplicationContext ctx) {
		cs.accept("++++++studyContext++++++\nBeanDefinitionCount=" + ctx.getBeanDefinitionCount());
		String[] beanNames = ctx.getBeanDefinitionNames();
		cs.accept("beanNames.length=" + beanNames.length);
		cs.accept("输出Bean的名称：");
		final String filter = "filter";
		final String listener = "listener";
		List<String> filters = new ArrayList<String>();
		List<String> listeners = new ArrayList<String>();
		Arrays.stream(beanNames).forEach((name)->{
			cs.accept("name=" + name);
			
			if (name.toLowerCase().contains(filter)) {
				filters.add(name);
			}
			if (name.toLowerCase().contains(listener)) {
				listeners.add(name);
			}
		});
		
		cs.accept("输出filters：");
		filters.forEach(item->{
			cs.accept("---F-" + item + "---{}" + ctx.getBean(item));
		});
		
		cs.accept("输出listeners：");
		listeners.forEach(item->{
			cs.accept("+++L+" + item + "+++{}" + ctx.getBean(item));
		});
		
//		cs.accept("---");
//		Arrays.stream(beanNames).forEach((name)->{
//			cs.accept(String.format("name=%s, bean=%s", name, ctx.getBean(name).toString()));
//		});
		
		cs.accept("------studyContext------");
	}

	/**
	 * 测试数据操作
	 * @author ben
	 * @date 2021-08-21 16:43:40 CST
	 * @param repository
	 * @return
	 */
//	@Bean
	@Deprecated
	public CommandLineRunner demo(UserCrudRepository repository) {
		return (args) -> {
			repository.save(new User("Jack", "Bauer"));
			repository.save(new User("Chloe", "O'Brian"));
			repository.save(new User("Kim", "Bauer"));
			repository.save(new User("David", "Palmer"));
			repository.save(new User("Michelle", "Dessler"));
			log.info("");
			
			log.info("Customer found with findByLastName('Bauer'):");
			log.info("--------------------------------------------");
			repository.findByLastName("Bauer").forEach(bauer -> {
				log.info(bauer.toString());
			});
			
			// 查找不存在的用户
			List<User> ulist = repository.findByLastName("Unexisted");
			log.info("Unexisted user：ulist={}", ulist);
			ulist.forEach(bauer -> {
				log.info(bauer.toString());
			});

			// 更新首个用户的age=10
			Optional<User> opuser1 = repository.findById(1L);
			opuser1.ifPresent(user -> {
				user.setAge(10);
				repository.save(user);
			});
			opuser1 = repository.findById(1L);
			log.info("after updated, user1={}", opuser1.isPresent() ? opuser1.get() : "user1不存在");
		};
	}

	
	@Resource
	RedisTemplate<String, Object> redisTemplate;
	
	/**
	 * 加快Redis作为缓存时的首次访问速度
	 * 应该还有其它办法
	 * @author ben
	 * @date 2021-09-04 15:37:27 CST
	 * @return
	 */
	@Bean
	public CommandLineRunner redisInit() {
		return (args) -> {
			cs.accept("redisInit...");
			redisTemplate.opsForValue().set("redisinit", 1, Duration.ofSeconds(1));
		};
	}
}
